﻿//-----------------------------------------------------------------------------
//<filedescription file="IntegrationKit.SWD.cs" company="Microsoft">
//  <copyright>
//     Copyright © Microsoft Corporation.  All rights reserved.
//     ***  DESIGNATED SAMPLE CODE (per the included software license terms) ***
//      THIS CODE SAMPLE IS MADE AVAILABLE TO YOU WITHOUT WARRANTY OF ANY KIND
//      AND CONFERS NO RIGHTS ON YOU WHATSOEVER EXCEPT THE RIGHT TO REVIEW IT
//      SOLELY AS A REFERENCE.  THE ENTIRE RISK OF USE OR RESULTS FROM USE OF
//      THIS CODE SAMPLE REMAINS WITH YOU.
//  </copyright>
//  <purpose>
//     Provides methods specific to Software Distribution
//     admin console.
//  </purpose>
//  <notes>
//  </notes>
//</filedescription>
//-----------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.IO;
using Microsoft.ConfigurationManagement.ManagementProvider;
using Microsoft.ConfigurationManagement.ManagementProvider.WqlQueryEngine;


namespace Microsoft.ConfigurationManagement.IntegrationDevelopmentKit
{
    /// <summary>
    /// 
    /// </summary>
    public partial class IntegrationKitUtilities
    {
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="packageName"></param>
        /// <param name="packageDescription"></param>
        /// <param name="packageSourcePath"></param>
        /// <param name="packageMfr"></param>
        /// <param name="packageVersion"></param>
        /// <returns></returns>
        public IResultObject CreatePackage(WqlConnectionManager connection, string packageName, string packageDescription, string packageSourcePath, string packageMfr, string packageVersion)
        {
            if (connection == null)
            {
                throw new System.ArgumentNullException("connection", Properties.Resources.Error_InvalidParameter);
            }
            if (string.IsNullOrEmpty(packageName))
            {
                throw new System.ArgumentNullException("packageName", Properties.Resources.Error_InvalidParameter);
            }
            if (Directory.Exists(packageSourcePath) == false)
            {
                throw new DirectoryNotFoundException("Package source path does not exist");

            }
            //Console.WriteLine("CreatePackage() passed initial section.");

            try
            {
                IResultObject newPackage = null;
                // first check and see if there is a duplicate package = if so, use that one and update it
                IResultObject newPackages = GetPackageByName(connection, packageName, PackageType.SWDPackage, packageVersion);
                if (newPackages != null)
                {
                    foreach (IResultObject obj in newPackages)
                    {
                        newPackage = obj;
                        break;
                    }
                }
                if (newPackage != null)
                {
                    //found a package
                    string newPackageID = IntegrationKitUtilities.GetROStringProperty(newPackage, "PackageID");
                    if (string.IsNullOrEmpty(newPackageID) == false)
                    {
                        //Console.WriteLine("Existing package will be updated."); 
                        newPackage = connection.GetInstance(@"SMS_Package.PackageID='" + newPackageID + "'");
                    }
                }
                else
                {
                    // Create new package object.
                    newPackage = connection.CreateInstance("SMS_Package");
                    if (newPackage == null)
                    {
                        //Console.WriteLine("new package object was null after CreateInstance.");
                        return null;
                    }
                    //Console.WriteLine("New package object instance created.");
                }


                // Populate new package properties.
                newPackage["Name"].StringValue = packageName;
                newPackage["Description"].StringValue = packageDescription;
                newPackage["PkgSourceFlag"].IntegerValue = (int)PackageSourceFlag.StorageDirect;
                newPackage["PkgSourcePath"].StringValue = packageSourcePath;
                newPackage["Manufacturer"].StringValue = packageMfr;
                newPackage["Version"].StringValue = packageVersion;
                newPackage["PackageType"].IntegerValue = (int)PackageType.SWDPackage;
                newPackage["PkgFlags"].IntegerValue = 0;

                //Console.WriteLine("New package properties added.");


                //unused properties (but still read/write)
                //newPackage["AlternateContentProviders"].StringValue = null;
                //newPackage["ExtendedData "].ByteArrayValue = null;
                //newPackage["ExtendedDataSize"].IntegerValue = null;
                //newPackage["ForcedDisconnectDelay"].IntegerValue = null;
                //newPackage["ForcedDisconnectEnabled"].BooleanValue = null;
                //newPackage["ForcedDisconnectNumRetries"].IntegerValue = null;
                //newPackage["Icon"].ByteArrayValue = null;
                //newPackage["IconSize"].IntegerValue = null;
                //newPackage["IgnoreAddressSchedule"].BooleanValue = null;


                // Save new package and new package properties.
                newPackage.AutoCommit = true;
                newPackage.Put();
                newPackage.AutoRefresh = true;
                newPackage.Get();

                string packageID = IntegrationKitUtilities.GetROStringProperty(newPackage, "PackageID");
                if (string.IsNullOrEmpty(packageID))
                {
                    //Console.WriteLine("Error creating package " + packageName + ". Could not get package ID");
                    return null;
                }
                //Console.WriteLine("Package.Put() executed successfully. Package ID of new package is " + packageID);



                // Output new package name.
                //Console.WriteLine("Created package" + packageName);
                return newPackage;
            }

            catch (SmsQueryException qex)
            {
                //Console.WriteLine("Exception occurred in CreatePackage() : " + qex.ExtendStatusErrorCode + "\n" + qex.Details + "\n" + qex.Data + "\n" + qex.TargetSite + "\n" + qex.InnerException + "\n" + qex.Message + "\n" + qex.StackTrace);
                IntegrationKitUtilities.LogException(LogFile, qex);
                return null;
            }
            catch (Exception ex)
            {
                //Console.WriteLine("Exception occured in CreatePackage().\n" + ex.Message);
                IntegrationKitUtilities.LogException(LogFile, ex);
                return null;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="packageID"></param>
        public bool DeletePackage(WqlConnectionManager connection, string packageID)
        {
            try
            {
                // Get the specified package instance (passed in as packageID).
                IResultObject packageToDelete = connection.GetInstance(@"SMS_Package.PackageID='" + packageID + "'");

                // Delete the package instance.
                packageToDelete.Delete();
                return true;

                // Output package ID of deleted package.
                //Console.WriteLine("Deleted Package ID: " + packageID);
            }

            catch (SmsException ex)
            {
                //Console.WriteLine("Failed to create package. Error: " + ex.Message);
                IntegrationKitUtilities.LogException(LogFile, ex);
                return false;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="packageName"></param>
        /// <param name="packageType"></param>
        /// <param name="packageVersion"></param>
        /// <returns></returns>
        public bool DeletePackage(WqlConnectionManager connection, string packageName, PackageType packageType, string packageVersion)
        {
            try
            {
                IResultObject packageObjects = GetPackageByName(connection, packageName, packageType, null);
                if (packageObjects == null)
                {
                    return false;
                }
                
                IResultObject packageToDelete = null;

                if (packageVersion != null)
                {
                    foreach (IResultObject obj in packageObjects)
                    {
                        string objVersion = GetROStringProperty(obj, "Version");
                        if (string.Compare(objVersion, packageVersion, StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            packageToDelete = obj;
                            break;
                        }
                    } 
                }
                if (packageToDelete == null)
                {
                    return false;
                }

                // Delete the package instance.
                packageToDelete.Delete();
                return true;
                // Output package ID of deleted package.
                //Console.WriteLine("Deleted Package ID: " + packageID);
            }

            catch (SmsException ex)
            {
                //Console.WriteLine("Failed to create package. Error: " + ex.Message);
                IntegrationKitUtilities.LogException(LogFile, ex);
                return false;
            }
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="existingPackageID"></param>
        /// <param name="newPackageDescription"></param>
        public void ConfigurePackageProperties(WqlConnectionManager connection, string existingPackageID, string newPackageDescription)
        {
            try
            {
                // Get specific package instance to modify.
                IResultObject packageToConfigure = connection.GetInstance(@"SMS_Package.PackageID='" + existingPackageID + "'");

                // Replace the existing package property with the new value (in this case the package description).
                packageToConfigure["Description"].StringValue = newPackageDescription;

                // Save package and modified package properties.
                packageToConfigure.AutoCommit = true;
                packageToConfigure.Put();

                // Output package ID and package name.
                //Console.WriteLine("Configured Package ");
                //Console.WriteLine("Package ID:        " + packageToConfigure["PackageID"].StringValue);
                //Console.WriteLine("Package Name:      " + packageToConfigure["Name"].StringValue);
            }

            catch (SmsException ex)
            {
                //Console.WriteLine("Failed to configure package. Error: " + ex.Message);
                IntegrationKitUtilities.LogException(LogFile, ex);
                
            }
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="existingPackageID"></param>
        /// <param name="siteCode"></param>
        /// <param name="serverName"></param>
        public void AssignPackageToDistributionPoint(WqlConnectionManager connection, string existingPackageID, string siteCode, string serverName)
        {
            try
            {
                // Create the distribution point object (this is not an actual distribution point).
                IResultObject distributionPoint = connection.CreateInstance("SMS_DistributionPoint");

                // Associate the package with the new distribution point object. 
                distributionPoint["PackageID"].StringValue = existingPackageID;

                // This query selects a single distribution point based on the provided siteCode and serverName.
                string query = "SELECT * FROM SMS_SystemResourceList WHERE RoleName='SMS Distribution Point' AND SiteCode='" + siteCode + "' AND ServerName='" + serverName + "'";

                // 
                IResultObject listOfResources = connection.QueryProcessor.ExecuteQuery(query);
                foreach (IResultObject resource in listOfResources)
                {
                    //Console.WriteLine(resource["SiteCode"].StringValue);
                    distributionPoint["ServerNALPath"].StringValue = resource["NALPath"].StringValue;
                    distributionPoint["SiteCode"].StringValue = resource["SiteCode"].StringValue;
                }

                // Save the distribution point object and properties.
                distributionPoint.AutoCommit = true;
                distributionPoint.Put();

                // Output package ID of assigned package.
                //Console.WriteLine("Assigned package: " + distributionPoint["PackageID"].StringValue);
            }

            catch (SmsException ex)
            {
                //Console.WriteLine("Failed to create package. Error: " + ex.Message);
                IntegrationKitUtilities.LogException(LogFile, ex);
                
            }
        }
        
    }
}